package chattingRoomNIO;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class ChatServerNIO {
    public static void main(String[] args) throws IOException{

        //缓冲区
        ByteBuffer readBuffer=ByteBuffer.allocate(1024);
        ByteBuffer writeBuffer=ByteBuffer.allocate(1024);


        //1.获取通道
        ServerSocketChannel ssChannel = ServerSocketChannel.open();

        //2.切换非阻塞模式
        ssChannel.configureBlocking(false);

        //3.绑定连接
        ssChannel.bind(new InetSocketAddress(8888));

        //4.获取选择器
        Selector selector = Selector.open();

        //5.将通道注册到选择器上，并且指定“监听接收事件”
        ssChannel.register(selector, SelectionKey.OP_ACCEPT);

        //6.轮训式的获获取选择器上的以及“准备就绪”的事件
        while(selector.select()>0){
            //7.获取当前选择器中所有注册的“选择键（已就绪的监听事件）”  遍历已经连接的通路
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while(it.hasNext()){
                //8.获取就绪的事件
                SelectionKey sk = it.next();
                //9.判断具体是什么事件准备就绪
                if(sk.isAcceptable()){
                    //10. 若“接受就绪” ，获取客户链接
                    SocketChannel sChannel = ssChannel.accept();
                    //11. 切换非阻塞模式
                    sChannel.configureBlocking(false);
                    //12. 将该通道注册到选择器上
                    sChannel.register(selector, SelectionKey.OP_READ);
                }else if(sk.isReadable()){
                    //13. 获取当前选择器上“读就绪”状态的通道
                    SocketChannel sChannel = (SocketChannel) sk.channel();
                    int len =0;
                    while((len =sChannel.read(readBuffer))>0){
                        readBuffer.flip();
                        System.out.println(new String(readBuffer.array(),0,len));
                        readBuffer.clear();
                    }


                }else if(sk.isWritable()){
                        SocketChannel sc= (SocketChannel) sk.channel();
                        sc.write(ByteBuffer.wrap("hello client~~".getBytes()));
                        //移除可写事件
                        sc.register(selector,sk.interestOps()-SelectionKey.OP_WRITE);

                    }
                }
                //15. 取消选择键 SelectionKey
                it.remove();
            }


    }

}
